//	ID: 066498650
//	Exercise #: 2
//	By:	Roy Moore
//
//	Written:	19/12/2011
//	Environment : VS2010
//
//-UDPTimeServer.cpp-

#include "UDPTimeServer.h"

void StartServer(SOCKET connSocket){
	BindSocketForServer(connSocket);

	sockaddr client_addr;

	MsgInfo serverMsgInfo;
	serverMsgInfo = InitMsgInfo();

	cout<<"Time Server: Wait for clients' requests.\n";	

	while(true)
	{
		RecvDataFrom(connSocket, &serverMsgInfo, &client_addr);

		char selectionChar;

		PrintStatus(Server, Recive, serverMsgInfo.bytesRecv, serverMsgInfo.recvBuff);
		//cout << "Time Server: Recieved: " << serverMsgInfo.bytesRecv << " bytes of \"" << serverMsgInfo.recvBuff << "\" message." << endl;

		selectionChar = serverMsgInfo.recvBuff[0];

		switch (selectionChar){
			case 'a':
				SendTime(connSocket, &serverMsgInfo, &client_addr);
				break;
			case 'b':
				SendTimeWithoutYear(connSocket, &serverMsgInfo, &client_addr);
				break;
			case 'c':
				SendTimeSinceEpoch(connSocket, &serverMsgInfo, &client_addr);
				break;
			case 'd':
				SendClientToServerDelayEstimation(connSocket, &serverMsgInfo, &client_addr);
				break;
			case 'e':
				ServerMeasureRTT(connSocket, &serverMsgInfo, &client_addr);
				break;
			case 'f':
				SendDayAndMounth(connSocket, &serverMsgInfo, &client_addr);
				break;
			case 'g':
				SendYear(connSocket, &serverMsgInfo, &client_addr);
				break;
			default :
				SendTime(connSocket, &serverMsgInfo, &client_addr);
		}
	}
}

void SendTime(SOCKET connSocket, MsgInfo *info, sockaddr * to_addr){
	time_t timer;

	time(&timer);
	strcpy(info->sendBuff, ctime(&timer));
	info->sendBuff[strlen(info->sendBuff)-1] = '\0'; //Need to end the string so we will know what size it is when sending

	SendDataTo(connSocket, info, to_addr);

	//cout << "Time Server: Sent: " << serverMsgInfo.bytesSent << "\\" << strlen(serverMsgInfo.sendBuff) << " bytes of \"" << serverMsgInfo.sendBuff << "\" message." << endl;	
	PrintStatus(Server, Send, info->bytesSent, info->sendBuff);
}

void SendTimeWithoutYear(SOCKET connSocket, MsgInfo *info, sockaddr * to_addr){
	char timeformat[] = "%H:%M:%S";

	SendTimeInFormat(timeformat, connSocket, info, to_addr);
}

void SendDayAndMounth(SOCKET connSocket, MsgInfo *info, sockaddr * to_addr){
	char timeformat[] = "%a %b";

	SendTimeInFormat(timeformat, connSocket, info, to_addr);
}

void SendYear(SOCKET connSocket, MsgInfo *info, sockaddr * to_addr){
	char timeformat[] = "%Y";

	SendTimeInFormat(timeformat, connSocket, info, to_addr);
}

void SendTimeInFormat(char* format, SOCKET connSocket, MsgInfo *info, sockaddr * to_addr){
	time_t timer;
	struct tm * timeinfo;

	time(&timer);
	timeinfo = localtime ( &timer );
	strftime(info->sendBuff, BUFFER_SIZE, format, timeinfo); //Hour:Minute:Second

	SendDataTo(connSocket, info, to_addr);

	//cout << "Time Server: Sent: " << serverMsgInfo.bytesSent << "\\" << strlen(serverMsgInfo.sendBuff) << " bytes of \"" << serverMsgInfo.sendBuff << "\" message." << endl;	
	PrintStatus(Server, Send, info->bytesSent, info->sendBuff);
}

void SendClientToServerDelayEstimation(SOCKET connSocket, MsgInfo *info, sockaddr * to_addr){
	SendTimeMs(connSocket, info, to_addr);
}

void ServerMeasureRTT(SOCKET connSocket, MsgInfo *info, sockaddr * to_addr){
	SendTimeMs(connSocket, info, to_addr);
}

void SendTimeMs(SOCKET connSocket, MsgInfo *info, sockaddr * to_addr){
	long time = GetTickCount();

	sprintf (info->sendBuff, "%lu", time);

	SendDataTo(connSocket, info, to_addr);

	//cout << "Time Server: Sent: " << serverMsgInfo.bytesSent << "\\" << strlen(serverMsgInfo.sendBuff) << " bytes of \"" << serverMsgInfo.sendBuff << "\" message." << endl;	
	PrintStatus(Server, Send, info->bytesSent, info->sendBuff);
}

void SendTimeSinceEpoch(SOCKET connSocket, MsgInfo *info, sockaddr * to_addr){
	time_t timer;

	time(&timer);
	sprintf (info->sendBuff, "%ld", timer);

	SendDataTo(connSocket, info, to_addr);

	//cout << "Time Server: Sent: " << serverMsgInfo.bytesSent << "\\" << strlen(serverMsgInfo.sendBuff) << " bytes of \"" << serverMsgInfo.sendBuff << "\" message." << endl;	
	PrintStatus(Server, Send, info->bytesSent, info->sendBuff);
}